15장 let,const 키워드와 블록레벨스코프
var로 선언한 변수의 문제점
- 변수 중복 선언 허용
- 함수 레벨 스코프
var은 함수의 코드블록만 지역 스코프로 인정해서 if문,for문 등에서 선언한 변수는 전역변수가 된다.
⇒ 전역변수가 남발하게 되고 전역변수 중복 선언되기 쉬움 - 변수 호이스팅
변수 호이스팅에 의해서 변수 선언문 이전에 변수 참조해도 에러 발생되지 않음
⇒ 가독성 떨어지고 오류 가능성
let 키워드
- 변수 중복 선언 금지
- 블록 레벨 스코프
- 변수 호이스팅
변수 호이스팅
let 키워드도 var 처럼 변수 호이스팅이 발생하지만, 발생하지 않는 것처럼 동작한다.
console.log(foo); // ReferenceError: foo is not defined
let foo;
var과 달리 let은 선언문 이전에 참조하면 에러가 발생
왜 let은 선언문 이전에 참조하면 에러가 발생할까?
var 키워드는 암묵적으로 선언 단계
와 초기화 단계
가 한번에 진행
선언 단계
에서 스코프( 실행 컨텍스트의 렉시컬 환경)에 식별자 등록해서 JS 엔진이 변수의 존재 알게하고, 초기화 단계
에서 undefined 로 변수 초기화
// var 키워드로 선언한 변수는 런타임 이전에 선언 단계와 초기화 단계가 실행된다.
// 따라서 변수 선언문 이전에 변수를 참조할 수 있다.
console.log(foo); // undefined
var foo;
console.log(foo); // undefined
foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1
let의 경우
선언 단계
와 초기화 단계
가 분리되어 진행
스코프 시작 지점부터 초기화 시작 지점까지 변수 참조할 수 없는 구간인 일시적 사각지대(TDZ)
가 존재.
따라서 선언문에서 초기화 하기 전에 변수를 참조하면 에러가 발생한다.
// 런타임 이전에 선언 단계가 실행된다. 아직 변수가 초기화되지 않았다.
// 초기화 이전의 일시적 사각 지대에서는 변수를 참조할 수 없다.
console.log(foo); // ReferenceError: foo is not defined
let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined
foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1
그럼 그냥 변수 호이스팅 발생 안하는 거랑 마찬가지 아니야?
let foo = 1; // 전역 변수
{
console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
let foo = 2; // 지역 변수
위 코드에서 두번째 foo가 스코프 내에서 호이스팅되어서 console.log(foo) 했을 때 전역 변수가 호출되지 않은 모습.
const 키워드
const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화 해야함.
let 처럼 변수 호이스팅이 일어나지 않은 것 처럼 동작
재할당이 금지되고 재할당 시 오류 발생
일반적으로 이름을 대문자로 선언
const 와 객체
const 변수는 재할당이 불가능하다 → 원시값은 변경 불가능한 값이므로 변경X
객체의 경우 값의 변경이 가능함 ⇒ const 변수에 할당된 객체 값 변경 가능
const person = {
name: 'Lee'
};
// 객체는 변경 가능한 값이다. 따라서 재할당없이 변경이 가능하다.
person.name = 'Kim';
console.log(person); // {name: "Kim"}
var vs. let vs. const
기본적으로 const
사용하고 재할당 필요할 경우에 let
을 사용하는 것이 좋다.
객체는 재할당하는 경우가 드믈어서 일단 const
사용하는게 좋다.